import * as https from 'https';
import { format } from "util";
import * as crypto from 'crypto';
import * as Koa from 'koa';
import { ServiceBase, Exceptions } from './../kalend';
import { weChatTokenSchema } from '../model/webchat'
import config from '../middleware/config';
import { customer_accountService } from './customer_account';
// var wxpay = require('./middleware/wxpay');
import { wxpay } from '../middleware/wxpay';
import * as  request from 'request';
import { customer_orderService } from './customer_order';
var xml2json = require("xmlparser");
var contentType = require('content-type')
import * as getRawBody from 'raw-body';
import { common } from '../middleware/common';
import { usertokenService } from './usertoken';
import { qrcodeService } from './qrcode';
import { logService } from './log';
import { paydatalogService } from './paydatalog';
import { datadictionaryService } from './datadictionary';
var xmlreader = require("xmlreader");
//const url = require('url')
import * as QRCodetorul from "qrcode";
import { fsfiles } from '../middleware/fsFiles';
import { merchant_wineService } from './merchant_wine';
var fs= require("fs")
const fxp = require("fast-xml-parser");
class MerchantcashService extends ServiceBase {
    //设置 WeChat 对象属性 config
    configjson: any = config.get("wechat");
    // 设置随机数
    noncestr: any = this.configjson["noncestr"];
    //设置 WeChat 对象属性 appID
    appID: any = this.configjson["appid"];
    //设置 WeChat 对象属性 appScrect
    appScrect: any = this.configjson["appsecret"];
    //设置 WeChat 对象属性 accessTokenUrl
    accessTokenUrl: any = this.configjson["accessTokenUrl"] + "?grant_type=%s&appid=%s&secret=%s";
    //设置 WeChat 对象属性 sessionUrl
    sessionUrl: any = this.configjson["sessionUrl"] + "?appid=%s&secret=%s&js_code=%s&grant_type=%s";
    //设置统一支付接口地址
    paytotal: any = this.configjson["paytotal"];
    // 商户id
    wx_mch_id: any = this.configjson["wx_mch_id"];
    // 商户密钥
    wx_mch_key: any = this.configjson["wx_mch_key"];
    // 支付回调函数
    notify_url: any = this.configjson["notify_url"];
    // 支付body
    paybody: any = this.configjson["paybody"];
    // 支付方式
    trade_type: any = this.configjson["trade_type"];
    // 二维码地址
    qrcodeurl: any = this.configjson["qrcodeurl"];
    // 设置 腾讯获取经纬度API
    locationUrl: any = this.configjson["locationUrl"] + "?address=%s&key=%s";
    // 设置 腾讯获取经纬度KEY
    locationKey: any = this.configjson["locationKey"];

    constructor() {
        super(weChatTokenSchema);
    }

    async requestGet(url: any) {
        return new Promise(function (resolve, reject) {
            https.get(url, function (res) {
                var buffer: any = [];
                var size = 0;
                //监听 data 事件
                res.on('data', function (data) {
                    buffer.push(data);
                    size += data.length;
                });
                //监听 数据传输完成事件
                res.on('end', function () {
                    let result = Buffer.concat(buffer, size).toString('utf-8');
                    resolve(result);
                });
            }).on('error', function (err) {
                reject(err);
            });
        });
    }
    async requestPOST(url: any, formData: any) {
     
        return new Promise((resolve, reject) => {
            request({ url: url, method: 'POST', body: formData,cert:fs.readFileSync(__dirname+ '/cert/apiclient_cert.pem'),key: fs.readFileSync(__dirname + '/cert/apiclient_key.pem') }, (err, response, body) => {
                if (!err && response.statusCode == 200) {
                    resolve(response);
                } else {
                    reject(err);
                }
            });
        });
    }


    /**
     * 根据URLcode获取对应的openid
     * https://api.weixin.qq.com/sns/oauth2/access_token?appid=APPID&secret=SECRET&code=CODE&grant_type=authorization_code
     */
    async getOpenidByCode(code: any) {
        let that = this;
        let res: any = {};
        if (code) {
            let result: any = await new Promise((resolve, reject) => {
                //格式化请求地址
                var url = format(that.sessionUrl, that.appID, that.appScrect, code, "authorization_code");
                //判断 本地存储的 access_token 是否有效
                return that.requestGet(url).then((data: any) => {
                    var res = JSON.parse(data);
                    console.log(res);
                    //将错误返回
                    resolve(res);
                });
            });
            if (result.openid) {
                // 保存用户信息
                //let userinit = await customer_accountService.creatnew({ appcode: code, openid: result.openid });
                // 返回用户登录态key随机子串
                res.token = common.createtokenStr();
                // 保存用户会话信息
                await usertokenService.create({
                    tokencode: res.token,
                    openid: result.openid,
                    appcode: result.code,
                    session_key: result.session_key,
                    remarks: '用户登录获取'
                });
                return res;
            } else {
                throw Exceptions.unknown(result);
            }
        } else {
            throw Exceptions.known('未取到用户凭证code');
        }
    }
    /**
     * 解密数据
     * @param token 
     * @param encryptedData 
     * @param iv 
     * @param code 
     */
    async decodeData(token: any, encryptedData: any, iv: any) {
        if (!token) {
            throw Exceptions.notoken();
        }
        let tokendata = (await usertokenService.getToken(token));
        var data = await this.decryptData(tokendata.session_key, encryptedData, iv);

        console.log('解密后 data: ', data)
        console.log('查询用户不存在，创建新用户');
        customer_accountService.creatnew({ phone: data.phoneNumber, openid: tokendata.openid, appcode: tokendata.appcode, session_key: tokendata.session_key, tokenid: tokendata._id });
        return data;
    }
 
     // 解密数据
     async decryptData(sessionkey: any, encryptedData: any, iv: any) {
      let that = this;
      // base64 decode
      //encryptedData = encryptedData.replace(/ /g, '+')
      //iv = iv.replace(/ /g, '+');
      var sessionKey = new Buffer(sessionkey, 'base64');
      encryptedData = new Buffer(decodeURIComponent(encryptedData), 'base64');
      iv = new Buffer(decodeURIComponent(iv), 'base64');


      let decoded: any;
      try {
          // 解密
          var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv);
          // 设置自动 padding 为 true，删除填充补位
          decipher.setAutoPadding(true);
          decoded = decipher.update(encryptedData, 'binary', 'utf8');
          decoded += decipher.final('utf8');

          decoded = JSON.parse(decoded)

      } catch (err) {
          console.log('解密第一次');
          console.log(err);
          // try {
          //     // 解密
          //     var decipher = crypto.createDecipheriv('aes-128-cbc', sessionKey, iv);
          //     // 设置自动 padding 为 true，删除填充补位
          //     decipher.setAutoPadding(true);
          //     decoded = decipher.update(encryptedData, 'binary', 'utf8');
          //     decoded += decipher.final('utf8');

          //     decoded = JSON.parse(decoded)
          // } catch (error) {
          //     console.log('解密第二次');
          //     console.log(err);
          // }
          throw Exceptions.unknown(err);
      }

      if (decoded.watermark.appid !== that.appID) {
          console.log('appid不匹配');
          throw new Error('appid不匹配')
      }

      return decoded;
  }
  raw(args: any) {
    var keys = Object.keys(args);
    keys = keys.sort()
    var newArgs: any = {};
    keys.forEach(function (key) {
        newArgs[key] = args[key];
    });
    var string = '';
    for (var k in newArgs) {
        string += '&' + k + '=' + newArgs[k];
    }
    string = string.substr(1);
    return string;
}
   //签名加密算法
   paysignjsapi(doc:any) {
   
    var string = this.raw(doc);
    var key = 'twogTlWEDM79SS2ZmzHT5ZPlUxsS1rZa';
    string = string + '&key=' + key;
    console.log('string=', string);
    return crypto.createHash('MD5').update(string, 'utf8').digest('hex').toUpperCase();
}
   async merchantcashpay(doc:any){
      var url="https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers";
      let fromdatamodel:any={
        xml: {
        mch_appid:'wx67d87001fe2776b8',
        mchid:1543353851,
        nonce_str:wxpay.createNonceStr(),
        partner_trade_no:doc.partner_trade_no,
        openid:doc.openid,
        check_name:'FORCE_CHECK',
        re_user_name:doc.wechatrealname,
        amount:doc.amount,
        desc:doc.desc,
        //spbill_create_ip:'120.55.166.72',//服务器地址
        spbill_create_ip:'61.50.187.136',//服务器地址
        
      }
      }
     var singstr= this.paysignjsapi(fromdatamodel.xml)

    fromdatamodel.xml.sign=singstr;

      var jston=JSON.stringify(fromdatamodel);

      const obj2xml = new fxp.j2xParser({
        format: true
      }).parse(fromdatamodel);

     console.log(__dirname);
     var res:any= await this.requestPOST(url,obj2xml);
      //return res.body;
     console.log(res);
    var prs=fxp.parse(res.body);
    //var tjson=JSON.stringify(prs);
      return  prs.xml;

      //console.log(JSON.stringify(xml2json)); 
  
   }
  
}

export const merchantcashService = new MerchantcashService();